#ifndef __BLOCKEDFILE_H__
#define __BLOCKEDFILE_H__

#include <string.h>
#include <fstream>
#include <cstdlib>

using namespace std;

enum TipoAperturaArchivo {
	//Crea un archivo nuevo, si ya existe es reemplazado, y es abierto para lectoescritura
	CREAR,
	//Abre un archivo para lectoescritura
	ABRIR
};

/*
 * Máscara para realizar lecturas y escrituras a disco de a bloques.
 */
class BlockedFile {
private:

protected:
	string nombre;
	int tamBloque;
	TipoAperturaArchivo tipoApertura;
	fstream flujo;
	bool error;

public:
	BlockedFile();
	//Contructor con parametros
	//path: el path y nombre de archivo
	//apertura: tipo de apertura
	//TamanioBloque: dado un entero, el tamanio del bloque es 2 a la "el entero dado"
	BlockedFile(string path, TipoAperturaArchivo apertura, int tamanioBloque);
	~BlockedFile();

	// se utiliza para inicializar el BlockedFile si se creo con el constructor default
	// retorna true si no se produce un error en la apertura
	bool init(string path, TipoAperturaArchivo apertura, int tamanioBloque);

	// cierra el archivo si está abierto
	void close();

	//Lee un bloque del archivo
	//Devuelve NULL si no se puede leer el bloque
	//Devuelve una copia del bloque leido, la cual DEBE LIBERARSE por el programador
	//Aloca tanta memoria como tamanioBloque
	//numeroBloque: el numero de bloque a escribir, comienza en 0
	char* readBloque(int numeroBloque);

	//Escribe un bloque en el archivo
	//Debe liberarse la memoria del bloque una vez utilizado
	//numeroBloque: el numero de bloque a escribir, comienza en 0
	//bloque: puntero a una porcion de memoria de tamanioBloque
	void writeBloque(int numeroBloque, char* bloque);

	//Devuelve el path completo del archivo
	string getNombre() { return this->nombre; };

	//Devuelve el tamanio del bloque en bytes del archivo
	int getTamanioBloque() { return this->tamBloque; };

	//Devuelve el tipo de apertura del archivo
	TipoAperturaArchivo getTipoApertura() { return this->tipoApertura; };

	//Devuelve true si hubo un error al intentar abrir, leer o escribir el archivo
	bool getError() { return this->error; };

	//Devuelve la cantidad de bloques que tiene el archivo
	int getCantBloques();

	/**********Metodos de utilidad genericos*******************/
	//Lee los bytes desde la posicionLectura(en bytes) y la cantidad de sizeLectura.
	char* readDatos(int posicionLectura,int sizeLectura);

	//Escribe los bytes desde la posicionEscritura(en bytes) con sizeEscritura y el dato en char*.
	void writeDatos(int posicionEscritura,int sizeEscritura,char * dato);

	/************Fin Metodos de Utilidad**********************/
};

#endif /*__BLOCKEDFILE_H__*/
